//数据劫持
class Observer {
  constructor(data) {
    this.observer(data);
  }

  observer(data) {
    if (!data || typeof data !== 'object') {
      return;
    }

    //获取对象里的属性名
    // console.log(Object.keys(data));
    //['message', 'count']

    //遍历拿到每一个属性名
    Object.keys(data).forEach(key => {
      this.defineReactive(data, key, data[key]);

      //对嵌套数据再次递归数据劫持
      this.observer(data[key]);
    });


  }

  //定义响应式方法
  defineReactive(obj, key, value) {
    let that = this;

    let dep = new Dep();

    Object.defineProperty(obj, key, {
      get() {
        //Dep.target -> Watcher实例
        Dep.target && dep.addSub(Dep.target);
        return value;
      },
      set(newValue) {
        if (newValue !== value) {
          //对新赋值的数据也要做数据劫持
          that.observer(newValue);

          value = newValue;

          // 通知观察者有新的值了，update相应的方法
          dep.notify();
        }
      }
    });

  }
}

//发布订阅
class Dep {
  constructor() {
    //订阅者
    this.subs = [];
  }

  //增加观察者
  addSub(watcher) {
    this.subs.push(watcher);
  }

  //通知
  //循环数组里每一个函数
  notify() {
    this.subs.forEach(watcher => watcher.update());
  }
}